package com.ucode.hrm.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.ucode.hrm.controller.service.ApiHrmDataPermissionService;
import com.ucode.hrm.controller.service.ApiHrmExcelHandleService;
import com.ucode.hrm.service.HrmCustomerCompanyService;
import com.ucode.hrm.service.HrmCustomerProjectService;
import com.ucode.hrm.service.HrmEmployeeService;
import com.ucode.hrm.service.HrmPaySlipService;
import com.ucode.model.hrm.HrmCustomerCompany;
import com.ucode.model.hrm.HrmCustomerProject;
import com.ucode.model.hrm.HrmPaySlip;
import com.ucode.model.hrm.convert.HrmPaySlipConvert;
import com.ucode.model.hrm.enums.HrmExcelTemplateEnum;
import com.ucode.model.hrm.vo.HrmPaySlipVO;
import com.ucode.tool.annotation.DataPermission;
import com.ucode.tool.annotation.NeedLogin;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.poi.excel.ExcelUtils;
import com.ucode.tool.util.CollectionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;

@Tag(name = "管理后台 - 人力资源系统 - 员工工资条")
@RestController
@RequestMapping("/hrm/pay-slip")
@Validated
public class HrmPaySlipController {
    private static final Log log = LogFactory.get();

    @Resource
    private HrmCustomerProjectService customerProjectService;
    @Resource
    private HrmCustomerCompanyService  customerCompanyService;
    @Resource
    private HrmEmployeeService employeeService;
    @Resource
    private ApiHrmDataPermissionService apiHrmDataPermissionService ;
    @Resource
    private ApiHrmExcelHandleService apiHrmExcelHandleService;
    @Resource
    private HrmPaySlipService hrmPaySlipService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/page-list")
    @Operation(summary = "获得分页列表")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:query')")
    @DataPermission(permissions={"hrm:pay-slip:query"})
    public ResponseResult<Paginator<HrmPaySlipVO>> pageList(
            @Schema(description = "客户公司编码") @RequestParam(value = "companyId",required = false) Long companyId,
            @Schema(description = "客户项目编码") @RequestParam(value = "projectId",required = false) Long projectId,
            @Schema(description = "员工名称") @RequestParam(value = "employeeName",required = false) String employeeName,
            @Schema(description = "身份证号") @RequestParam(value = "idCard",required = false) String idCard,
            @Schema(description = "批次号") @RequestParam(value = "batchnum",required = false) String batchnum,
            @Schema(description = "员工可见") @RequestParam(value = "visible",required = false) Boolean visible,
            @Schema(description = "费用月份区间",example = "[2022-07-01,2022-07-01]")  @RequestParam(value = "feeMonthInterval",required = false) LocalDate[] feeMonthInterval,
            @Schema(description = "页码",example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @Schema(description = "每页记录数",example="5") @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize){

        Map<String,Object> condition = new HashMap<>();
        if(StrUtil.isNotBlank(employeeName))
            condition.put("employeeName", StrUtil.concat(true,"%", employeeName,"%"));
        if(StrUtil.isNotBlank(idCard))
            condition.put("idCard", StrUtil.concat(true,"%", idCard,"%"));
        if(ArrayUtil.isNotEmpty(feeMonthInterval) && feeMonthInterval.length == 2){
            condition.put("startTime",feeMonthInterval[0]);
            condition.put("endTime",feeMonthInterval[1]);
        }
        condition.put("companyId",companyId);
        condition.put("batchnum",batchnum);
        condition.put("visible",visible);

        Set<Long> customerProjectIds = apiHrmDataPermissionService.getCurrentUserCustomerProjectIdsByDataPermission();
        //没有可查看的数据
        if(ObjUtil.isNotNull(customerProjectIds) && customerProjectIds.size() == 0){
            return ResponseResult.success(new Paginator<>());
        }

        //没有权限查看指定项目的数据
        if(ObjUtil.isNotNull(projectId) && ObjUtil.isNotNull(customerProjectIds) && !customerProjectIds.contains(projectId)){
            throw new UcodeServiceException(GlobalResultCodeEnum.UN_DATA_PERMISSION);
        }
        condition.put("projectIds",customerProjectIds);
        condition.put("projectId",projectId);
        condition.put("deltag",false);
        return ResponseResult.success(pageList(condition,pageNum,pageSize));
    }

    private Paginator<HrmPaySlipVO> pageList(Map<String,Object> condition, int pageNum, int pageSize) {
        Paginator<HrmPaySlip> paginator = hrmPaySlipService.queryPageForList(condition,pageSize,pageNum);
        Paginator<HrmPaySlipVO> paginatorVO =  HrmPaySlipConvert.INSTANCE.convertPage(paginator);

        if(CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> customerCompanyIds =   CollectionUtils.convertSet( paginatorVO.getList(),HrmPaySlipVO::getCompanyId);
            Set<Long> projectIds =   CollectionUtils.convertSet( paginatorVO.getList(),HrmPaySlipVO::getProjectId);
            Map<Long, HrmCustomerCompany> customerCompanyMap = customerCompanyService.getMap(customerCompanyIds);
            Map<Long, HrmCustomerProject> projectMap = customerProjectService.getMap(projectIds);
            paginatorVO.getList().forEach(item -> {
                HrmCustomerCompany customerCompany = customerCompanyMap.get(item.getCompanyId());
                if(customerCompany != null)
                    item.setCompanyName(customerCompany.getCompanyName());

                HrmCustomerProject project = projectMap.get(item.getProjectId());
                if(project != null)
                    item.setProjectName(project.getProjectName());
            });
        }

        return paginatorVO;
    }

    @GetMapping("/getById/{id}")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH,example = "1024")
    @Operation(summary = "主键获得信息")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:query')")
    public ResponseResult<HrmPaySlipVO> getById(@PathVariable(name="id",required=true) Long id){
        HrmPaySlip bean = hrmPaySlipService.validate(id);
        HrmPaySlipVO vo = HrmPaySlipConvert.INSTANCE.convert(bean);
        if(ObjUtil.isNotNull(vo.getCompanyId())){
            HrmCustomerCompany customerCompany = customerCompanyService.selectByPrimaryKey(bean.getCompanyId());
            if(customerCompany != null)
                vo.setCompanyName(customerCompany.getCompanyName());
        }

        if(ObjUtil.isNotNull(vo.getProjectId())){
            HrmCustomerProject project = customerProjectService.selectByPrimaryKey(bean.getProjectId());
            if(project != null)
                vo.setProjectName(project.getProjectName());
        }

        return ResponseResult.success(vo);
    }

    @PostMapping("/logic-delete/{id}")
    @Operation(summary = "转移到回收站")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:logic-delete')")
    public ResponseResult<Object> logicDelete(@PathVariable(name="id",required=true) Long id) {
        //逻辑删除
        int i = hrmPaySlipService.logicDeletePrimaryKey(id);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @PostMapping("/batch-logic-delete")
    @Operation(summary = "批量转移到回收站")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:logic-delete')")
    public ResponseResult<Boolean> batchLogicDeletePrimaryKey(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                @RequestParam(value = "ids",required = true) List<Long> ids) {
        int i = hrmPaySlipService.logicDeleteByPrimaryKeys(ids);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @NeedLogin
    @GetMapping("/export")
    @Operation(summary = "导出")
    public void export(HttpServletResponse response) throws IOException {
        ExcelUtils.write(response, HrmExcelTemplateEnum.PAYSLIP_TEMPLATE.getName(), HrmExcelTemplateEnum.PAYSLIP_TEMPLATE.getName(), new HashMap(), new ArrayList<>());
    }

    @NeedLogin
    @GetMapping("/export-tpl")
    @Operation(summary = "导出模板")
    public void exportTpl(HttpServletResponse response) throws IOException {
        ExcelUtils.write(response, HrmExcelTemplateEnum.PAYSLIP_TEMPLATE.getName(), HrmExcelTemplateEnum.PAYSLIP_TEMPLATE.getName(), new HashMap(), new ArrayList<>());
    }

    @PostMapping("/import") // 映射到/api/excel/parse
    @Operation(summary = "导入")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:create')")
    public ResponseResult<Boolean> importPaySlipData(@RequestParam("file") MultipartFile file) throws IOException {
        apiHrmExcelHandleService.importPaySlipData(file);
        return ResponseResult.success();
    }

    @PostMapping("/setting")
    @Operation(summary = "工资条设置")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:setting')")
    public ResponseResult<Boolean> setting(@RequestParam(value = "showColumns",required = true) List<String> showColumns) {
        hrmPaySlipService.setPaySlipShowColumns(showColumns);
        return ResponseResult.success();
    }

    @GetMapping("/get-setting")
    @Operation(summary = "获取工资条设置")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:setting')")
    public ResponseResult<List<String>> getSetting(){
        return ResponseResult.success(hrmPaySlipService.getPaySlipShowColumns());
    }

    @PostMapping("/batch-update-visible")
    @Operation(summary = "批量更新可见状态")
    @PreAuthorize("@usfs.hasPermission('hrm:pay-slip:update-visible')")
    public ResponseResult<Boolean> batchUpdateVisible(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                      @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                      @RequestParam(value = "ids",required = true) List<Long> ids,
                                                      @Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                      @RequestParam(value = "visible",required = true) Boolean visible
    ) {
        int i = hrmPaySlipService.updateVisibleByIds(ids, visible);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

}
